home *** CD-ROM | disk | FTP | other *** search
- /*% cc -O -K -i -s -o fortune %
- */
- /*
- * Fetch a fortune from the Fortunes file by randomly seeking
- * within that file and then searching for the Nth next fortune,
- * ( 0 <= N <= 15). If EOF is reached, rewind and continue.
- * This two step process minimizes file i/o while making the frequency
- * of each fortune realtively independent of the size of its predecessors.
- *
- * Display the selected fortune, replacing @ characters with newlines.
- * This format (single line fortunes) allows foreign fortunes to be
- * merged into a local file with common lines deleted by sort -u
- *
- * If called with any argument, repeat until killed.
- *
- */
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
-
- char *Fortunes = "fortunes";
-
- #define LEN 2048
- char line[LEN];
-
- main(argc, argv)
- char **argv;
- {
- long p;
- register l;
- register char *q;
- time_t t;
- FILE *f;
- struct stat sbuf;
- char *fortenv;
-
- if ( (fortenv = getenv ("FORTUNES")) != NULL )
- Fortunes = fortenv;
-
- if (argc >= 3 && !strcmp(argv[1], "-f")) {
- Fortunes = argv[2]; argv += 2; argc -= 2;
- }
- f = fopen(Fortunes, "r");
- if (f == NULL) {
- write(1,"Memory fault -- core dumped\n", 29);
- exit(1);
- }
- time(&t);
- srand(getpid() ^ (int)((t>>16) ^ t));
- fstat(fileno(f), &sbuf);
- do {
- p = rand() % sbuf.st_size;
- fseek(f, p, 0);
- for (l=((rand())&07); l-- >= 0; ) {
- fgets(line, LEN, f);
- if (fgets(line, LEN, f) == NULL || line[0] == 0) {
- rewind(f);
- fgets(line, LEN, f);
- }
- }
- for(q = line; *q++;)
- if ( *q == '@')
- *q = '\n';
- l = (q - line) -1;
- write(1, line, l);
- } while (argc > 1);
- exit(0);
- }
-
- char *
- fgets(s, n, f)
- register char *s;
- register n;
- FILE *f;
- {
- register c;
- register char *p;
-
- p=s;
- while (--n>0) {
- if ((c = getc(f)) == EOF)
- break;
- if ((*s++ = c) == '\n')
- break;
- }
- *s = 0;
- if (p == s)
- return NULL;
- return p;
- }
-
-